<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8" />
        <title>深拷贝和浅拷贝</title>
    </head>
    <body>
        <script>
            /*
             * 深拷贝
             * 定义：修改新变量值不影响原来变量的值
             * 例如：默认情况下基本数据类型都是浅拷贝
             * */

            let p1 = 1;
            let p2 = p1;
            p2 = 2;
            console.log(p1);
            console.log(p2);
            /*
             * 浅拷贝
             * 定义：修改新变量值影响原来变量的值
             * 例如：默认情况下引用数据类型都是浅拷贝
             * */
            const obj1 = { name: "zs", age: 1 };
            const obj2 = obj1;
            obj2.name = "li";
            console.log(obj1);
            console.log(obj2);
            console.log("------------");
        </script>

        <script>
            <!-- 对象深拷贝-->
            const obj3 = new Object();
            obj3.name = obj1.name;
            obj3.age = obj1.age;
            obj3.name = "ww";
            console.log(obj1);
            console.log(obj3);
            console.log("------------");

            const obj4 = new Object();
            for (let key in obj1) {
                obj4[key] = obj1[key];
            }
            obj4.name = "zl";
            console.log(obj1);
            console.log(obj4);
            console.log("------------");

            const obj5 = new Object();
            Object.assign(obj5, obj1);

            obj5.name = "zz";
            console.log(obj1);
            console.log(obj5);
            console.log("------------");

            const obj = {
                key1: "123",
                key2: [1, 2, 3],
                key3: {
                    name: "z",
                    age: 1,
                },
                key4: function (name) {
                    console.log("func:", name);
                },
            };
            const obj6 = new Object();
            function deepCopy(target, source) {
                //遍历所有属性
                for (let key in source) {
                    //获取值
                    const value = source[key];

                    //检测值是否为引用类型
                    if (value instanceof Object) {
                        //引用数据类型根据构造函数创建对象
                        console.log(
                            "value.constructor:",
                            value.constructor,
                            value.constructor.name
                        );
                        if (value.constructor.name === "Function") {
                            //函数类型直接赋值
                            target[key] = value;
                        } else {
                            const subTarget = new value.constructor();
                            //对象赋值
                            target[key] = subTarget;
                            //递归调用给子对象赋值
                            deepCopy(subTarget, value);
                        }
                    } else {
                        //基本数据类型直接赋值
                        target[key] = value;
                    }
                }
            }
            deepCopy(obj6, obj);
            obj6.key3.name = 2;
            obj6.key2[0] = 10;
            console.log(obj);
            console.log(obj6);
            obj.key4("hah");
            console.log("obj6.key4:", obj6.key4);

            obj6.key4("hah");

            console.log("------------");
        </script>
    </body>
</html>
